package com.nali.dal.statement.function.formatter;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.nali.dal.statement.function.DataHandler;
import com.nali.dal.statement.function.FunctionArgument;
import com.nali.dal.statement.function.FunctionException;

/**
 * Decode<br>&nbsp;
 * [target1, target2, 1, 2, 3, 4] = if(target1==1&&target2==2)3;else4;
 * [target1, target2, 1, 2, 3, 4, 5, 6] = if(target1==1&&target2==2)3;if(target1==4&&target2==5)6;else exception!
 * size%3==2||0
 * @author sam Created on 2011-4-12
 */
@Component
public class DecodePair implements DataHandler<Object> {
	@Autowired
	private Decode decode;

	@Override
	public Object handle(List<Object> argList) throws FunctionException {
		int size = argList.size();
		int newSize = 1 + ((size - 2) / 3) * 2 + (size % 3 == 0 ? 1 : 0);
		List<Object> newArgList = new ArrayList<Object>(newSize);
		newArgList.add(new Pair(argList.get(0), argList.get(1)));
		boolean pair=true;
		int i=2;
		do {
			if(pair && i != size -1) {
				newArgList.add(new Pair(argList.get(i++), argList.get(i++)));
			} else {
				newArgList.add(argList.get(i++));
			}
			pair^=true;
		} while(i < size);
		Object rlt = decode.handle(newArgList);
		if(rlt==newArgList.get(0)) {
			throw new FunctionException("not match value for:" + argList.subList(0, 2)
					+ " in:" + argList.subList(2, argList.size()));
		}
		return rlt;
	}

	@Override
	public void validate(List<FunctionArgument> arguments) throws FunctionException {
		if(arguments == null || arguments.size() < 5) {
			throw new FunctionException("Datahandler: " + this.getClass() + ", at least 5 argument");
		}
		if(arguments.size() % 3 == 1) {
			throw new FunctionException("Datahandler: " + this.getClass() + ", arguments' size must be 3n or 3n+2");
		}
	}
	
	static class Pair {
		Object o1;
		Object o2;
		public Pair(Object o1, Object o2) {
			super();
			this.o1 = o1;
			this.o2 = o2;
		}
		@Override
		public boolean equals(Object obj) {
			if (obj instanceof Pair) {
				Pair target = (Pair) obj;
				return Decode.eq(target.o1, o1) && Decode.eq(target.o2, o2);
			} else {
				return false;
			}
		}
		//没有重写hashcode，因为不会用到collection
	}
}
